home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyo (Python 2.5)
-
- __revision__ = '$Id: stanzaprocessor.py 668 2007-01-05 16:24:08Z jajcus $'
- __docformat__ = 'restructuredtext en'
- import libxml2
- import logging
- import threading
- from pyxmpp.expdict import ExpiringDictionary
- from pyxmpp.exceptions import ProtocolError, BadRequestProtocolError, FeatureNotImplementedProtocolError
- from pyxmpp.stanza import Stanza
-
- class StanzaProcessor:
-
- def __init__(self):
- self.me = None
- self.peer = None
- self.initiator = None
- self.peer_authenticated = False
- self.process_all_stanzas = True
- self._iq_response_handlers = ExpiringDictionary()
- self._iq_get_handlers = { }
- self._iq_set_handlers = { }
- self._message_handlers = []
- self._presence_handlers = []
- self._StanzaProcessor__logger = logging.getLogger('pyxmpp.Stream')
- self.lock = threading.RLock()
-
-
- def process_response(self, response):
- if response is None or response is False:
- return False
-
- if isinstance(response, Stanza):
- self.send(response)
- return True
-
-
- try:
- response = iter(response)
- except TypeError:
- return bool(response)
-
- for stanza in response:
- if isinstance(stanza, Stanza):
- self.send(stanza)
- continue
-
- return True
-
-
- def process_iq(self, stanza):
- sid = stanza.get_id()
- fr = stanza.get_from()
- typ = stanza.get_type()
- if typ in ('result', 'error'):
- if fr:
- ufr = fr.as_unicode()
- else:
- ufr = None
- if self._iq_response_handlers.has_key((sid, ufr)):
- key = (sid, ufr)
- elif (fr == self.peer and fr == self.me or fr == self.me.bare()) and self._iq_response_handlers.has_key((sid, None)):
- key = (sid, None)
- else:
- self._StanzaProcessor__logger.warning('ignoring stanza from %r', fr)
- self._StanzaProcessor__logger.warning('I am %r', self.me)
- self._StanzaProcessor__logger.warning(self._iq_response_handlers.keys())
- return False
- (res_handler, err_handler) = self._iq_response_handlers[key]
- if stanza.get_type() == 'result':
- response = res_handler(stanza)
- else:
- response = err_handler(stanza)
-
- try:
- del self._iq_response_handlers[key]
- self.process_response(response)
- except KeyError:
- pass
-
- return True
-
- q = stanza.get_query()
- if not q:
- raise BadRequestProtocolError, 'Stanza with no child element'
-
- el = q.name
- ns = q.ns().getContent()
- if typ == 'get':
- if self._iq_get_handlers.has_key((el, ns)):
- response = self._iq_get_handlers[(el, ns)](stanza)
- self.process_response(response)
- return True
- else:
- raise FeatureNotImplementedProtocolError, 'Not implemented'
- elif typ == 'set':
- if self._iq_set_handlers.has_key((el, ns)):
- response = self._iq_set_handlers[(el, ns)](stanza)
- self.process_response(response)
- return True
- else:
- raise FeatureNotImplementedProtocolError, 'Not implemented'
- else:
- raise BadRequestProtocolError, 'Unknown IQ stanza type'
-
-
- def __try_handlers(self, handler_list, typ, stanza):
- namespaces = []
- if stanza.xmlnode.children:
- c = stanza.xmlnode.children
- while c:
-
- try:
- ns = c.ns()
- except libxml2.treeError:
- ns = None
-
- if ns is None:
- c = c.next
- continue
-
- ns_uri = ns.getContent()
- if ns_uri not in namespaces:
- namespaces.append(ns_uri)
-
- c = c.next
-
- for handler_entry in handler_list:
- t = handler_entry[1]
- ns = handler_entry[2]
- handler = handler_entry[3]
- if t != typ:
- continue
-
- if ns is not None and ns not in namespaces:
- continue
-
- response = handler(stanza)
- if self.process_response(response):
- return True
- continue
-
- return False
-
-
- def process_message(self, stanza):
- if not (self.initiator) and not (self.peer_authenticated):
- self._StanzaProcessor__logger.debug('Ignoring message - peer not authenticated yet')
- return True
-
- typ = stanza.get_type()
- if self._StanzaProcessor__try_handlers(self._message_handlers, typ, stanza):
- return True
-
- if typ != 'error':
- return self._StanzaProcessor__try_handlers(self._message_handlers, 'normal', stanza)
-
- return False
-
-
- def process_presence(self, stanza):
- if not (self.initiator) and not (self.peer_authenticated):
- self._StanzaProcessor__logger.debug('Ignoring presence - peer not authenticated yet')
- return True
-
- typ = stanza.get_type()
- if not typ:
- typ = 'available'
-
- return self._StanzaProcessor__try_handlers(self._presence_handlers, typ, stanza)
-
-
- def route_stanza(self, stanza):
- if stanza.get_type() not in ('error', 'result'):
- r = stanza.make_error_response('recipient-unavailable')
- self.send(r)
-
- return True
-
-
- def process_stanza(self, stanza):
- self.fix_in_stanza(stanza)
- to = stanza.get_to()
- if not (self.process_all_stanzas) and to and to != self.me and to.bare() != self.me.bare():
- return self.route_stanza(stanza)
-
-
- try:
- if stanza.stanza_type == 'iq':
- if self.process_iq(stanza):
- return True
-
- elif stanza.stanza_type == 'message':
- if self.process_message(stanza):
- return True
-
- elif stanza.stanza_type == 'presence':
- if self.process_presence(stanza):
- return True
-
- except ProtocolError:
- e = None
- typ = stanza.get_type()
- if typ != 'error':
- pass
- None if typ != 'result' or stanza.stanza_type != 'iq' else stanza.stanza_type != 'iq'
- e.log_ignored()
-
- self._StanzaProcessor__logger.debug('Unhandled %r stanza: %r' % (stanza.stanza_type, stanza.serialize()))
- return False
-
-
- def check_to(self, to):
- if to != self.me:
- return None
-
- return to
-
-
- def set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
- self.lock.acquire()
-
- try:
- self._set_response_handlers(iq, res_handler, err_handler, timeout_handler, timeout)
- finally:
- self.lock.release()
-
-
-
- def _set_response_handlers(self, iq, res_handler, err_handler, timeout_handler = None, timeout = 300):
- self.fix_out_stanza(iq)
- to = iq.get_to()
- if to:
- to = to.as_unicode()
-
- if timeout_handler:
- self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout, timeout_handler)
- else:
- self._iq_response_handlers.set_item((iq.get_id(), to), (res_handler, err_handler), timeout)
-
-
- def set_iq_get_handler(self, element, namespace, handler):
- self.lock.acquire()
-
- try:
- self._iq_get_handlers[(element, namespace)] = handler
- finally:
- self.lock.release()
-
-
-
- def unset_iq_get_handler(self, element, namespace):
- self.lock.acquire()
-
- try:
- if self._iq_get_handlers.has_key((element, namespace)):
- del self._iq_get_handlers[(element, namespace)]
- finally:
- self.lock.release()
-
-
-
- def set_iq_set_handler(self, element, namespace, handler):
- self.lock.acquire()
-
- try:
- self._iq_set_handlers[(element, namespace)] = handler
- finally:
- self.lock.release()
-
-
-
- def unset_iq_set_handler(self, element, namespace):
- self.lock.acquire()
-
- try:
- if self._iq_set_handlers.has_key((element, namespace)):
- del self._iq_set_handlers[(element, namespace)]
- finally:
- self.lock.release()
-
-
-
- def __add_handler(self, handler_list, typ, namespace, priority, handler):
- if priority < 0 or priority > 100:
- raise ValueError, 'Bad handler priority (must be in 0:100)'
-
- handler_list.append((priority, typ, namespace, handler))
- handler_list.sort()
-
-
- def set_message_handler(self, typ, handler, namespace = None, priority = 100):
- self.lock.acquire()
-
- try:
- if not typ:
- typ == 'normal'
-
- self._StanzaProcessor__add_handler(self._message_handlers, typ, namespace, priority, handler)
- finally:
- self.lock.release()
-
-
-
- def set_presence_handler(self, typ, handler, namespace = None, priority = 100):
- self.lock.acquire()
-
- try:
- if not typ:
- typ = 'available'
-
- self._StanzaProcessor__add_handler(self._presence_handlers, typ, namespace, priority, handler)
- finally:
- self.lock.release()
-
-
-
- def fix_in_stanza(self, stanza):
- pass
-
-
- def fix_out_stanza(self, stanza):
- pass
-
-
- def send(self, stanza):
- raise NotImplementedError, 'This method must be overriden in derived classes.'
-
-
-